Relocatable ocamlbuild#372
Conversation
Makefile.config contains copies of PREFIX, BINDIR, LIBDIR and MANDIR from OCaml's Makefile.config. These values were not actually being used, and they are potentially less reliable with Relocatable OCaml. They've therefore been removed. OCAML_LIBDIR was previously a copy of LIBDIR from OCaml's Makefile.config. However, this file is found by running `ocamlc -where`, which itself _gives_ the value for OCAML_LIBDIR. For Relocatable OCaml, `ocamlc -where` is guaranteed to be correct, where the LIBDIR value may not be, so tweak the generation of Makefile.config to use this value instead.
In configure.make, specifying a path beginning ./ or ../ or OCAMLBUILD_LIBDIR enables Relocatable ocamlbuild, as long as the ocamlbuild binary is being installed in the same directory as the compiler and the compiler itself is Relocatable OCaml. The relative path given for OCAMLBUILD_LIBDIR describes how to get from OCaml's Standard Library to the directory containing the "ocamlbuild" package directory (in opam, this is just ".."). In this mode, `ocamlbuild -where` is determined relative to the Standard Library.
PREFIX became prefix quietly in OCaml 4.08
gasche
left a comment
There was a problem hiding this comment.
I am trying to understand your PR and made various small questions/comments.
Here is the big picture I got from reading the code (your explanation are more confusing than this, but I suppose it's because I haven't absorbed the full subtlety yet):
- if the user passes an absolute path in OCAML_BUILDIR, it is passed as-is in ocamlbuild_config.ml
- if the user passes a relative path in OCAML_BUILDIR and the OCaml compiler is relocatable, it is passed as-is
- if the user passes a relative path in OCAMLBUILD_DIR and the compiler is not relocatable, (OCAML_DIR / OCAML_BUILDIR) (where OCAML_DIR is typically
ocamlc -where) is passed
Naive question: ocamlbuild also has modes where it builds plugins, by calling the compiler rather than by dynamic linking. Is that also supported in relocation scenarios?
| $(OCAML_MANDIR)) | ||
|
|
||
| # OCAMLBUILD_RELOCATABLE is true if: | ||
| # 1. The compiler is Relocatable OCaml |
There was a problem hiding this comment.
This is a bit obscure to me. Maybe "The compiler supports relocation and the 'standard_library_relative' configuration variable"?
|
|
||
| # OCAMLBUILD_RELOCATABLE is true if: | ||
| # 1. The compiler is Relocatable OCaml | ||
| # 2. ocamlbuild will be installed in the same directory as the compiler |
There was a problem hiding this comment.
The ocamlbuild binary will be installed in the same directory as the compiler binaries. My first reaction was that of course they should be installed in their own separate directories (I was thinking of libraries).
| OCAML_PREFIX = $(PREFIX) | ||
| OCAML_BINDIR = $(BINDIR) | ||
| OCAML_LIBDIR = $(LIBDIR) | ||
| OCAML_PREFIX = $(prefix) |
There was a problem hiding this comment.
Why is there a change from $PREFIX to $prefix?
| let libdir = | ||
| if libdir = ".." then | ||
| (* Cheeky special case, as it happens to match opam *) | ||
| Filename.dirname ocaml_libdir |
There was a problem hiding this comment.
I don't understand, are there clear benefits to passing dirname ocaml_libdir rather than ocaml_libdir/..?
| src/ocamlbuild_config.ml: OCAML_LIBDIR = | ||
| src/ocamlbuild_config.ml: LIBDIR_ABS = | ||
|
|
||
| OCB_EXTRA_LINKFLAGS = \ |
There was a problem hiding this comment.
Could you maybe use the same approach as above to clarify the parallel?
Makefile.config: OCB_EXTRA_LINKFLAGS = \
...
This PR adds support to ocamlbuild to take advantage of OCaml 5.5's relocatable mode. You can see it in action from a 5.5 or 5.6 trunk opam switch by running:
This is "correct" operation at this point - once that binary is in a switch, the directory portion before the
..would be the switch'sbindirectory.To be relocatable,
ocamlbuild -wherewill receive the location of the OCaml Standard Library at runtime (that's what Relocatable OCaml does) and then needs to know the relative path to concatenate to it, rather than simply storing the full absolute path.What actually has to be done when building ocamlbuild to achieve this is very simple: when linking ocamlbuild, the flag
-set-runtime-default standard_library_default=$(ocamlopt -config-var standard_library_relative)must be passed toocamlc/ocamopt. A small bit of extra code is then added to the bottom ofocamlbuild_config.mlwhich uses the same mechanism as the compiler'sConfigmodule to determine the location at runtime of the standard library, and thus where ocamlbuild's standard library is.What is slightly more complicated is doing that in the general way exposed by
configure.make, and invoking that from ocamlbuild.opam. There are obviously multiple ways to do it, but the one I've done here is slightly simpler in the opam file, at a cost of slightly more complexity inconfigure.make.The idea is that if
OCAMLBUILD_LIBDIRis an explicit-relative path (i.e. it's.,..or starts./or../) then it describes the relative path fromocamlopt -whereto the directory which contains theocamlbuildlibrary directory. In opam, that's just..- for an opam switch,ocamlopt -whereis the same as$(opam var lib)/ocamland the ocamlbuild library files are installed in$(opam var lib)/ocamlbuild, which is$(ocamlopt -where)/../ocamlbuild.The simplification I've then made for opam is to have ocamlbuild.opam always specify
OCAMLBUILD_LIBDIR=... It is just converted to an absolute path if the compiler being used is not relocatable. Note that this still makes semantic sense (just): previously, we passedOCAMLBUILD_LIBDIR=%{lib}%, but we know in opam thatocamlopt -whereis%{lib}%/ocaml... in other words, if the compiler is not relocatable, then we'll effectively takeOCAMLBUILD_LIBDIR=$(dirname $(ocamlopt -where))which is...%{lib}%!